package ferp.core.ai.filter;

import ferp.core.card.Card;
import ferp.core.game.Game;
import ferp.core.player.Hand;

/**
 * User: igorgok
 * Date: 9/9/12 4:53 PM
 */
public class FilterDeclarerFirstHandMoveOpen
{
  public static int apply(int candidates, Card.Suit trump, int declarer, int[] hands)
  {
    int filtered = 0;

    // get trump suit
    int t = Card.Set.get(candidates, trump);

    // resolve opponents and their trump suits
    int p1 = Game.next(declarer);
    int t1 = Card.Set.get(hands[p1], trump);

    int p2 = Game.next(p1);
    int t2 = Card.Set.get(hands[p2], trump);

    if (Card.Set.size(t) > 0)
    {
      // if declarer has trump cards but opponents don't then all trump candidates can be removed
      if (Card.Set.size(t1) + Card.Set.size(t2) == 0)
        filtered = Hand.remove(candidates, trump);
      else
        if (canMoveWithHighestTrump(t, t1, t2))
          filtered = Hand.add(0, trump, Card.Set.highest(t));
    }

    return filtered == 0 ? candidates : filtered;
  }

  private static boolean canMoveWithHighestTrump(int t, int t1, int t2)
  {
    while (t != 0 && (t1 != 0 || t2 != 0))
    {
      Card.Rank h  = Card.Set.highest(t);
      Card.Rank h1 = Card.Set.higher(t1, h); Card.Rank l1 = Card.Set.lowest(t1);
      Card.Rank h2 = Card.Set.higher(t2, h); Card.Rank l2 = Card.Set.lowest(t2);

      // even if one of the opponents has trump higher than declarer's highest one,
      // declarer can move with the highest trump if his trump's suit length greater by more than 1
      // opponent's having longest trump suit
      if ((h1 != null || h2 != null) && Hand.size(t) - Math.max(Hand.size(t1), Hand.size(t2)) < 2)
        return false;

      t  = Hand.remove(t, h.hash());

      if (l1 != null)
        t1 = Hand.remove(t1, l1.hash());

      if (l2 != null)
        t2 = Hand.remove(t2, l2.hash());
    }

    return true;
  }
}
